#include "QtUtil.h"

namespace QtUtil {
QLabel* createLabel(
    QWidget* parent,
    const QString& text,
    Qt::Alignment alignment,
    const QString& name
)
{
    QLabel* label = new QLabel(parent);
    label->setObjectName(name);
    label->setAlignment(alignment);
    label->setText(text);
    return label;
}

QLineEdit* createLineEdit(QWidget* parent, const QString& name)
{
    QLineEdit* edit = new QLineEdit(parent);
    edit->setObjectName(name);
    edit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    return edit;
}

QLineEdit* createPassword(QWidget* parent, const QString& name)
{
    QLineEdit* edit = new QLineEdit(parent);
    edit->setObjectName(name);
    edit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    edit->setEchoMode(QLineEdit::Password);
    return edit;
}

QPushButton* createButton(
    QWidget* parent,
    const QString& name,
    const QString& text
)
{
    QPushButton* button = new QPushButton(parent);
    button->setObjectName(name);
    button->setText(text);
    return button;
}

QComboBox* createComboBox(
    QWidget* parent,
    const QString& name,
    const QStringList& items,
    const QStringList& keys
)
{
    QComboBox* combo = new QComboBox(parent);
    combo->setObjectName(name);
    int i = 0;
    for (const QString item : items) {
        combo->addItem(item, keys[i]);
        i++;
    }
    return combo;
}

QCheckBox* createCheckBox(
    QWidget* parent,
    const QString& text,
    const QString& name
)
{
    QCheckBox* input = new QCheckBox(parent);
    input->setObjectName(name);
    input->setText(text);
    return input;
}

QSpinBox* createSpinBox(QWidget* parent, const QString& name, int defaultValue)
{

    QSpinBox* editor = new QSpinBox(parent);
    editor->setObjectName(name);
    editor->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    editor->setRange(-999999999, 999999999);
    editor->setValue(defaultValue);
    return editor;
}

QDoubleSpinBox* createDoubleSpinBox(
    QWidget* parent,
    const QString& name,
    double defaultValue
)
{

    QDoubleSpinBox* editor = new QDoubleSpinBox(parent);
    editor->setObjectName(name);
    editor->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    editor->setRange(-999999.999, 999999.999);
    editor->setDecimals(3);
    editor->setValue(defaultValue);
    return editor;
}

QTableWidget* createTableWidget(
    QWidget* parent,
    const QString& name,
    const QStringList& headers,
    const vector<int>& columnWidths
)
{

    QTableWidget* table = new QTableWidget(1, headers.size(), parent);
    table->setObjectName(name);
    table->setHorizontalHeaderLabels(headers);
    table->setAlternatingRowColors(true);
    table->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows
    );
    table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    table->horizontalHeader()->setFixedHeight(24);
    // table->horizontalHeader()->setFrameShape(QFrame::NoFrame);
    table->horizontalHeader()->setStretchLastSection(true);
    table->horizontalHeader()->setHighlightSections(false);
    table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    int i = 0;
    for (int width : columnWidths) {
        table->setColumnWidth(i, width);
        i++;
    }
    table->setStyleSheet(
        "QTableCornerButton::section { background-color:#F0F0F0;}"
        "QHeaderView::section { background-color:#F0F0F0; margin:4px 8px 4px "
        "8px; border:none;}"
    );

    return table;
}

QMenu* createMenu(QMenuBar* parent, const QString& name, const QString& title)
{
    QMenu* menu = new QMenu(parent);
    menu->setObjectName(name);
    menu->setTitle(title);
    parent->addAction(menu->menuAction());
    return menu;
}

QToolBar* createToolBar(
    shared_ptr<ApplicationContext> context,
    const QString& name
)
{
    QToolBar* toolBar = new QToolBar(context->mainWindow());
    toolBar->setObjectName(name);
    context->mainWindow()->addToolBar(Qt::TopToolBarArea, toolBar);
    return toolBar;
}

void createMenuSeparator(QMenu* menu)
{
    menu->addSeparator();
}

QVBoxLayout* createVerticalLayout(QWidget* parent, const QString& name)
{
    QVBoxLayout* verticalLayout = new QVBoxLayout(parent);
    verticalLayout->setObjectName(name);
    return verticalLayout;
}

QHBoxLayout* createHorizontalLayout(QWidget* parent, const QString& name)
{
    QHBoxLayout* horizontalLayout = new QHBoxLayout(parent);
    horizontalLayout->setObjectName(name);
    return horizontalLayout;
}

QGridLayout* createGridLayout(const QString& name)
{
    QGridLayout* gridLayout = new QGridLayout();
    gridLayout->setSpacing(0);
    gridLayout->setObjectName(name);
    gridLayout->setContentsMargins(0, 0, 0, 0);
    return gridLayout;
}

QTabWidget* createTabWidget(QWidget* parent, const QString& name)
{
    QTabWidget* tabWidget = new QTabWidget(parent);
    tabWidget->setObjectName(name);
    return tabWidget;
}

QTabWidget* createTabWidget(
    QWidget* parent,
    const QString& name,
    QRect geometry
)
{
    QTabWidget* tabWidget = new QTabWidget(parent);
    tabWidget->setObjectName(name);
    if (!geometry.isNull()) {
        tabWidget->setGeometry(geometry);
    }
    return tabWidget;
}

QWidget* createTab(
    QTabWidget* tabWidget,
    const QString& name,
    const QString& label
)
{
    QWidget* tab = new QWidget();
    tab->setObjectName(name);
    tabWidget->addTab(tab, label);
    // tabWidget.setTabText(tabWidget.indexOf(tab), label);
    return tab;
}

void messageBox(QWidget* parent, const QString& title, const QString& message)
{
    QMessageBox::information(parent, title, message);
}

QIcon* createIcon(const QString& iconFile)
{
    QIcon* icon = new QIcon();
    icon->addFile(iconFile, QSize(), QIcon::Normal, QIcon::Off);
    // icon.actualSize
    return icon;
}

void showErrorMessageBox(
    shared_ptr<ApplicationContext> context,
    std::exception& e
)
{
    QMessageBox::critical(
        context->mainWindow(), context->ProductName, e.what()
    );
}

void showErrorMessageBox(
    shared_ptr<ApplicationContext> context,
    const QString& message
)
{
    QMessageBox::critical(context->mainWindow(), context->ProductName, message);
}

double getRandomDouble()
{
    double value = QRandomGenerator::global()->generateDouble();
    return value * 1000;
}
} // namespace QtUtil
